Everything changes and nothing stands still.
—Heraclitus of Ephesus, as quoted by Plato in Cratylus (360 BCE)
上面那段話是書中的引言,數據系統無可避免的需要改變,我們在 Day 3 時有介紹過 Evolvability (進化能力) ,我們設計的系統應該讓改變變的簡單;當資料格式或 schema 有變更時,相對應系統的新版本程式應該要同時部署且執行,然而,在大型的數據系統中,程式變更是不會立即發生的:
於 server-side 部署系統時,你會希望執行 rolling upgrade (滾動式升級),意思為一次只部署新版本的程式到小量的機器上,讓系統能持續運作,且能做到服務不斷線,因此就能鼓勵更密集的釋出新版本程式,讓系統更有 evolvability (進化能力)。
在 client-side,你只能希望 user 能更新應用軟體,所以會有一群沒同步更新應用軟體的 user。
這意味著舊的程式跟新的程式要並行,代表系統要同時:
Backward compatibility (向前兼容)
新程式要能讀舊程式寫入的資料。
Forward compatibility (向後兼容)
舊程式要能讀新程式寫入的資料。
向前兼容很好理解,你在寫與新 schema 有關的程式時就會一併考慮舊的資料該怎麼讀取,向後兼容就有點 tricky 了,代表你的程式要能忽略所有未來可能加入的額外資訊或欄位。
在往後幾天會介紹數個資料編碼方式,包含 JSON, XML, Protocol Buffers, Thrift 和 Avro,然後也會看該如何兼容,最後則會提到資料溝通模式,像 REST, RPC, 訊息佇列。
資料在程式中通常會以 2 種方式表達 (最少 2 種) :
所以,我們必須有某種翻譯方法讓程式得以在這 2 種方式中做切換,從記憶體中的資料結構翻譯成連續的位元組稱為 encoding (編譯),也可稱 serialization (序列化) 或 marshalling (編組);反之稱做 decoding (解譯),也可稱 parsing, deserialization 或 unmarshalling,接下來就來介紹各種不同的 encoding 格式啦!
顧名思義,就是每個程式語言內建的 encoding 格式啦,比如 Java 就是 java.io.Serializable
,Ruby 是 Marshal
,Python 是 pickle
,除此之外還有其他第三方 library 提供,例如 Java 的 Kryo,這些 encoding 方式看起來方便,但可能會有以下幾個問題:
所以正常工程師會選擇其他的 encoding 格式。
然後,為了敘述方便,其他的 encdoing 格式就明天介紹啦!
我們公司只有在做 POC 專案的時候才會考慮用 Language-Specific Format,在正式開發時會全部替換掉,畢竟你不能圖一時的方便然後讓未來的工程想來砍你,有時寫程式時會想像未來接手的工程師都是喪心病狂的瘋子 XD